package com.manli.api.service;

import java.util.Date;

import javax.xml.parsers.DocumentBuilderFactory;

import com.manli.api.dao.wechat.WeChatUserInfoDao;
import com.manli.api.dto.wechat.WeChatUserLocation;
import com.manli.api.service.wechat.WeChatUserInfoService;
import com.manli.api.service.wechat.WeChatUserLocationService;
import com.manli.api.util.WeChatOverUtil;
import com.manli.wechat.pojo.WeChatMiniProgramUserInfo;
import com.manli.wechat.pojo.WeChatUserInfo;
import com.manli.wechat.pojo.WechatMiniAutoCode2Session;
import com.manli.wechat.utils.WeChat;
import com.manli.wechat.utils.WeChatUserManage;
import com.manli.wechat.utils.WechatMiniUserInfoConvertToWechatUserInfo;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.manli.api.dto.SysWechatConfig;
import com.manli.api.util.WeChatConfigUtil;
import com.manli.api.util.XmlTool;
import com.manli.qq.weixin.mp.aes.WXBizMsgCrypt;

@Service
@Transactional
public class WechatService {
	
	@Autowired
	WeChatConfigUtil weChatConfigUtil;

	@Autowired
	WeChatOverUtil weChatOverUtil;

	@Autowired
	WeChatUserInfoService weChatUserInfoService;

	@Autowired
	WeChatUserLocationService weChatUserLocationService;

	/**
	 * 微信公众号发来消息 (兼容模式获取安全模式)
	 * @param msg
	 * @param msg_signature
	 * @param timestamp
	 * @param nonce
	 * @param echostr
	 * @return
	 * @throws Exception 
	 */
	public String receiveMsg(String appId,String msg, String msg_signature, String timestamp, String nonce, String echostr)  throws Exception {
		SysWechatConfig sysWechatConfig = weChatConfigUtil.getWeChatByAppid(appId);
		String token = sysWechatConfig.getServerToken();
		String encodingAesKey = sysWechatConfig.getEncodingAesKey();
		
		WXBizMsgCrypt pc = new WXBizMsgCrypt(token, encodingAesKey, appId);
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
		dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
		dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
		dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
		dbf.setXIncludeAware(false);
		dbf.setExpandEntityReferences(false);
		String result = pc.decryptMsg(msg_signature, timestamp, nonce, msg);
		JSONObject msgObject = XmlTool.documentToJSONObject(result);
		JSONArray array = (JSONArray) JSONArray.parse(msgObject.get("xml").toString());
		JSONObject content = array.getJSONObject(0);
		String returnMsg = "success";
		switch (content.get("MsgType").toString()) {
		case "text":
			returnMsg = "已经收到您的文字消息";
			break;
		case "image":
			returnMsg = "已经收到您的图片消息";
			break;
		case "voice":
			returnMsg = "已经收到您的声音消息";
			break;
		case "video":
			returnMsg = "已经收到您的视频消息";
			break;
		case "shortvideo":
			returnMsg = "已经收到您的小视频消息";
			break;
		case "link":
			returnMsg = "已经收到您的链接消息";
			break;
		case "event"://接收事件
			returnMsg = weixinEvent(content);
			break;
		default:
			break;
		}
		//返回给微信服务器
        return replyToWeChatForText(returnMsg,content,appId,token,encodingAesKey);
	}
	/**
	 * 微信时间 关注 取消关注 扫码带参数的二维码
	 * @param content
	 * @return
	 */
	private String weixinEvent(JSONObject content) throws Exception {
		String event = content.get("Event").toString();
		String returnMsg = "success";
		switch (event) {
		case "subscribe":
			String eventKey = null;
			//保存关注的微信信息
			WeChatUserInfo weChatUserInfo = saveUpdateWeChatUserInfo(content.get("FromUserName").toString());
			returnMsg = "感谢您的关注";
			if(content.containsKey("EventKey")) {//没关注扫带参数二维码
				returnMsg = eventKeyService(content.getString("EventKey"),content.getString("Ticket"));//"EventKey:"+content.getString("EventKey")+",Ticket:"+content.getString("Ticket");
				weChatUserInfo.setEventKey(content.getString("EventKey"));
				weChatUserInfoService.updateById(weChatUserInfo);
			}
			break;
		case "unsubscribe":
			returnMsg = "取消关注了";
			saveUpdateWeChatUserInfo(content.get("FromUserName").toString());
			break;
		case "SCAN"://已经关注扫带参数二维码
			if(content.containsKey("EventKey")) {//没关注扫带参数二维码
				eventKeyService(content.getString("EventKey"),content.getString("Ticket"));
				returnMsg = "";//"EventKey:"+content.getString("EventKey")+",Ticket:"+content.getString("Ticket");
			}
			break;
		case "LOCATION":
			//写入地址上报 获取用户定位
			returnMsg = "您的经纬度："+content.getString("Longitude")+","+content.getString("Precision");
			WeChatUserLocation location = new WeChatUserLocation();
			location.setLongitude(content.getString("Longitude"));//地理位置经度
			location.setLatitude(content.getString("Latitude"));//地理位置纬度
			location.setOpenid(content.get("FromUserName").toString());
			location.setCreateTime(new Date());
			weChatUserLocationService.save(location);
			break;
		default:
			break;
		}
		return returnMsg;
	}

	public String eventKeyService(String eventKey , String ticket){

		return "" ;
	}

	public WeChatUserInfo saveUpdateWeChatUserInfo(String fromUserName) throws Exception {
		//向微信询问用户信息状态
		String appId = "wx6f56d14c68184b2f";//漫狸科技(温州)
		SysWechatConfig config = weChatConfigUtil.getWeChatByAppid(appId);
		WeChat weChat = new WeChat(config.getAppId(), config.getAppSecret());
		WeChatUserManage weChatUserManage = new WeChatUserManage(config.getAppId(), config.getAppSecret());
		JSONObject json = weChatUserManage.getUserUnionId(weChatOverUtil.getAccessToken(weChat),fromUserName);
		WeChatUserInfo weChatUserInfo = weChatUserManage.getUserUnionIdFromJSONObject(json);
		//判断是否存在
		WeChatUserInfo checkIsExistBean = weChatUserInfoService.getByUnionidOrOpenid(weChatUserInfo.getUnionid(),weChatUserInfo.getOpenid());
		if( checkIsExistBean == null ){
			//不存在 insert
			//微信公众号
			weChatUserInfo.setSource(1);
			return weChatUserInfoService.save(weChatUserInfo);
		}else{
			//存在则更新
			checkIsExistBean.setSubscribe(weChatUserInfo.getSubscribe());
			if (weChatUserInfo.getHeadimgurl() != null){
				checkIsExistBean.setHeadimgurl(weChatUserInfo.getHeadimgurl());
			}
			if (weChatUserInfo.getUnionid() != null){
				checkIsExistBean.setUnionid(weChatUserInfo.getUnionid());
			}
			if (weChatUserInfo.getSubscribe_time() != null){
				checkIsExistBean.setSubscribe_time(weChatUserInfo.getSubscribe_time());
			}
			weChatUserInfoService.updateById(checkIsExistBean);
			return checkIsExistBean;
		}
	}

	/**
	 * 小程序保存到用户表中
	 * @param wechatMiniAutoCode2Session
	 * @return
	 * @throws Exception
	 */
	public WeChatUserInfo saveUpdateWeChatMiniProgramUserInfo(WechatMiniAutoCode2Session wechatMiniAutoCode2Session, WeChatMiniProgramUserInfo miniProgramUserInfo) throws Exception {
		//判断是否存在
		WeChatUserInfo checkIsExistBean = weChatUserInfoService.getByUnionidOrOpenid(wechatMiniAutoCode2Session.getUnionid(),wechatMiniAutoCode2Session.getOpenid());
		WeChatUserInfo weChatUserInfo = WechatMiniUserInfoConvertToWechatUserInfo.covert(miniProgramUserInfo);
		if( checkIsExistBean == null ){
			//不存在 insert
			weChatUserInfo.setUnionid(miniProgramUserInfo.getUnionId());
			weChatUserInfo.setOpenid(miniProgramUserInfo.getOpenId());
			//小程序
			weChatUserInfo.setSource(2);
			return weChatUserInfoService.save(weChatUserInfo);
		}else{
			//存在则更新
			if (weChatUserInfo.getHeadimgurl() != null){
				checkIsExistBean.setHeadimgurl(weChatUserInfo.getHeadimgurl());
			}
			if (weChatUserInfo.getUnionid() != null){
				checkIsExistBean.setUnionid(weChatUserInfo.getUnionid());
			}
			if (weChatUserInfo.getSubscribe_time() != null){
				checkIsExistBean.setSubscribe_time(weChatUserInfo.getSubscribe_time());
			}
			if (weChatUserInfo.getNickname() != null){
				checkIsExistBean.setNickname(weChatUserInfo.getNickname());
			}
			weChatUserInfoService.updateById(checkIsExistBean);
			return checkIsExistBean;
		}
	}

	/**
	 * 返回微信TXT
	 * @param returnMsg
	 * @param content
	 * @return
	 * @throws Exception
	 */
	public String replyToWeChatForText(String returnMsg, JSONObject content , String appId, String token ,String encodingAesKey) throws Exception {
		String nowTime = System.currentTimeMillis()+"";
		String nonce = nowTime;//随机数
		
		String replyMsg = "<xml>\r\n" + 
				"  <ToUserName>"+content.getString("FromUserName")+"</ToUserName>\r\n" + 
				"  <FromUserName>"+content.getString("ToUserName")+"</FromUserName>\r\n" + 
				"  <CreateTime>"+nowTime+"</CreateTime>\r\n" + 
				"  <MsgType>text</MsgType>\r\n" + 
				"  <Content>"+returnMsg+"</Content>\r\n" + 
				"  <MsgId>"+nowTime+"</MsgId>\r\n" + 
				"</xml>";
		
		WXBizMsgCrypt pc = new WXBizMsgCrypt(token, encodingAesKey, appId);
		String encryptReplyMsg = pc.encryptMsg(replyMsg, nowTime, nonce);
		
		return encryptReplyMsg;
	}
}
